#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include "../../source/sorting/sort.h"

const int DEFAULT_CNT = 10;

void gen_nums(int argc, char ** argv, std::vector<int> & nums)
{
    int cnt = DEFAULT_CNT;
    if(argc == 2)
    {
        cnt = std::atoi(argv[1]);
    }
    if(argc < 3)
    {
        srand(time(NULL));
        int up_bound = (100 < cnt) ? cnt*10 : 1000;
        for(int i = 0; i < cnt; ++ i)
        {
            nums.push_back(rand() % up_bound);
        }
    }
    else
    {
        for(int i = 1; i < argc; ++ i)
        {
            nums.push_back(std::atoi(argv[i]));
        }
    }
}

template <typename T>
inline void print(T t)
{
    std::cout << t << " ";
}

template <typename T>
void disp_vector(std::vector<T> & v, const char * description)
{
    std::cout << description << std::endl;
    std::for_each(v.begin(), v.end(), print<T>);
    std::cout << std::endl << std::endl;
}

extern inline void swap(int nums[], int pos1, int pos2);

int main(int argc, char ** argv)
{
    std::vector<int> nums;
    std::vector<int> seconds;
    int start_time = 0;

    gen_nums(argc, argv, nums);
    disp_vector(nums, "Raw sequence:");

    std::vector<int> sorted(nums);
    try
    {
        start_time = time(NULL);
        quick_sort_array_in_place(&(sorted.at(0)), 0, nums.size() - 1);
        seconds.push_back((int)(std::time(NULL) - start_time));
    }
    catch(std::string err)
    {
        std::cout << err << std::endl;
        return -1;
    }
    disp_vector(sorted, "Sorted by in place quick sort:");

    std::copy(nums.begin(), nums.end(), sorted.begin());
    start_time = time(NULL);
    insertion_sort_array(&(sorted.at(0)), nums.size());
    seconds.push_back(std::time(NULL) - start_time);
    disp_vector(sorted, "Sorted by insertion sort:");

    std::copy(nums.begin(), nums.end(), sorted.begin());
    start_time = time(NULL);
    selection_sort_array(&(sorted.at(0)), nums.size());
    seconds.push_back(std::time(NULL) - start_time);
    disp_vector(sorted, "Sorted by slection sort:");

    disp_vector(seconds, "Time used for each:");
    return 0;
}

